/**
 * 
 */
package org.alipay4j;

import java.util.HashMap;
import java.util.Map;

import org.alipay4j.component.AbstractComponent;
import org.alipay4j.component.life.AccountComponent;
import org.alipay4j.component.life.AdvertComponent;
import org.alipay4j.component.life.DataComponent;
import org.alipay4j.component.life.ExtensionComponent;
import org.alipay4j.component.life.GroupComponent;
import org.alipay4j.component.life.LabelComponent;
import org.alipay4j.component.life.LifeAgentComponent;
import org.alipay4j.component.life.LifeSettingComponent;
import org.alipay4j.component.life.MenuComponent;
import org.alipay4j.component.life.MessageComponent;
import org.alipay4j.component.life.QrcodeComponent;
import org.alipay4j.component.life.SceneComponent;
import org.alipay4j.component.life.TopicComponent;
import org.alipay4j.component.life.UserComponent;
import org.alipay4j.component.life.UserLabelComponent;
import org.alipay4j.component.util.BaseComponent;
import org.alipay4j.component.util.SnsComponent;
import org.alipay4j.loader.DefaultTokenLoader;
import org.alipay4j.loader.ITokenLoader;
import org.alipay4j.model.base.Token;
import org.alipay4j.util.ObjectHelper;

/**
 * 支付宝平台基础支持对象
 * @author heliang
 *
 */
public class Alipay extends AlipaySupport implements java.io.Serializable {
	/** */
	private static final long serialVersionUID = 7091354825224310361L;
	/** 同步锁 */
    private final static byte[] LOCK = new byte[0];
    /** appid */
    private String appId;
    /** 平台配置信息  */
    private AlipayConfig alipayConfig;
    /** 支付宝支付相关配置 */
    private AlipayPayConfig alipayPayConfig;
    /** Token加载器  */
    protected ITokenLoader tokenLoader = new DefaultTokenLoader();
    /** 组件集 */
    private final Map<String, AbstractComponent> components = new HashMap<String, AbstractComponent>();
    
    /** 单公众号，并且只支持一个公众号方式（配置文件）,不支持分布式 */
	public Alipay() {
		super();
		this.appId = Configuration.getAppId();
		//读取配置文件，加载生活号配置
		this.alipayConfig = new AlipayConfig();
		alipayConfig.setAppid(Configuration.getAppId());
		alipayConfig.setAlipayGateway(Configuration.getAlipayGateway());
		alipayConfig.setAppPriKey(Configuration.getAppPriKey());
		alipayConfig.setAlipayPubKey(Configuration.getAlipayRsaPukKey());
		alipayConfig.setAppGateway(Configuration.getAppGateway());
		alipayConfig.setAppAuthUri(Configuration.getAppOauthUri());
		alipayConfig.setUserAuthUri(Configuration.getUserOauthUri());
		alipayConfig.setAppAesKey(Configuration.getAppAesKey());
		alipayConfig.setAppAuthToken(Configuration.getAppAuthToken());
		//读取配置文件，加载支付配置
		this.alipayPayConfig = new AlipayPayConfig();
	}
	
	/** 多公众号，不支持分布式 */
	public Alipay(AlipayConfig alipayConfig) {
		super();
		this.appId = alipayConfig.getAppid();
		this.alipayConfig = alipayConfig;
	}
	
	/** 多公众号，不支持分布式，包含支付配置 */
	public Alipay(AlipayConfig alipayConfig,AlipayPayConfig payConfig) {
		super();
		this.appId = alipayConfig.getAppid();
		this.alipayConfig = alipayConfig;
		this.alipayPayConfig = payConfig;
	}

	
	/** 支付配置 */
	public Alipay(AlipayPayConfig payConfig) {
		super();
		this.alipayPayConfig = payConfig;
	}

	/**
     * 获取Token对象
     *
     * @return Token对象
     * @throws org.weixin4j.WeixinException 微信操作异常
     * @since 0.1.0
     */
    public Token getToken() throws AlipayException {
        Token token = tokenLoader.get(this.appId);
        if (token == null) {
            synchronized (LOCK) {
                token = tokenLoader.get(this.appId);
                if (token == null) {
                    //获得Configuration里面的token
                	String tokenStr = this.alipayConfig.getAppAuthToken();
                	if(ObjectHelper.isNotEmpty(tokenStr)) {
                		token = new Token(); 
                		token.setAppAuthToken(tokenStr);
                	}
                    tokenLoader.refresh(this.appId,token);
                }
            }
        } 
        return token;
    }
    
    /** 返回基础授权组件 */
    public BaseComponent base() {
        String key = BaseComponent.class.getName();
        if (components.containsKey(key)) {
            return (BaseComponent) components.get(key);
        }
        BaseComponent component = new BaseComponent(this);
        components.put(key, component);
        return component;
    }
    /** 返回用户相关授权组件 */
    public SnsComponent sns() {
        String key = SnsComponent.class.getName();
        if (components.containsKey(key)) {
            return (SnsComponent) components.get(key);
        }
        SnsComponent component = new SnsComponent(this);
        components.put(key, component);
        return component;
    }
    /** 生活号账户操作组件 */
    public AccountComponent account() {
        String key = AccountComponent.class.getName();
        if (components.containsKey(key)) {
            return (AccountComponent) components.get(key);
        }
        AccountComponent component = new AccountComponent(this);
        components.put(key, component);
        return component;
    }
    
    /** 返回用户组件 */
    public UserComponent user() {
        String key = UserComponent.class.getName();
        if (components.containsKey(key)) {
            return (UserComponent) components.get(key);
        }
        UserComponent component = new UserComponent(this);
        components.put(key, component);
        return component;
    }
    /** 广告位操作组件 */
    public AdvertComponent advert() {
        String key = AdvertComponent.class.getName();
        if (components.containsKey(key)) {
            return (AdvertComponent) components.get(key);
        }
        AdvertComponent component = new AdvertComponent(this);
        components.put(key, component);
        return component;
    }
    /** 数据统计组件  */
    public DataComponent data() {
        String key = DataComponent.class.getName();
        if (components.containsKey(key)) {
            return (DataComponent) components.get(key);
        }
        DataComponent component = new DataComponent(this);
        components.put(key, component);
        return component;
    }
    /** 扩展区组件  */
    public ExtensionComponent extension() {
        String key = ExtensionComponent.class.getName();
        if (components.containsKey(key)) {
            return (ExtensionComponent) components.get(key);
        }
        ExtensionComponent component = new ExtensionComponent(this);
        components.put(key, component);
        return component;
    }
    /** 分组操作组件 */
    public GroupComponent group() {
        String key = GroupComponent.class.getName();
        if (components.containsKey(key)) {
            return (GroupComponent) components.get(key);
        }
        GroupComponent component = new GroupComponent(this);
        components.put(key, component);
        return component;
    }
    /** 标签操作组件 */
    public LabelComponent label() {
        String key = LabelComponent.class.getName();
        if (components.containsKey(key)) {
            return (LabelComponent) components.get(key);
        }
        LabelComponent component = new LabelComponent(this);
        components.put(key, component);
        return component;
    }
    
    /** 生活号操作组件 */
    public LifeAgentComponent lifeAgent() {
        String key = LifeAgentComponent.class.getName();
        if (components.containsKey(key)) {
            return (LifeAgentComponent) components.get(key);
        }
        LifeAgentComponent component = new LifeAgentComponent(this);
        components.put(key, component);
        return component;
    }
    /** 生活号设置组件  */
    public LifeSettingComponent lifeSetting() {
        String key = LifeSettingComponent.class.getName();
        if (components.containsKey(key)) {
            return (LifeSettingComponent) components.get(key);
        }
        LifeSettingComponent component = new LifeSettingComponent(this);
        components.put(key, component);
        return component;
    }
    /** 目录操作组件 */
    public MenuComponent menu() {
        String key = MenuComponent.class.getName();
        if (components.containsKey(key)) {
            return (MenuComponent) components.get(key);
        }
        MenuComponent component = new MenuComponent(this);
        components.put(key, component);
        return component;
    }
    /** 消息操作组件 */
    public MessageComponent message() {
        String key = MessageComponent.class.getName();
        if (components.containsKey(key)) {
            return (MessageComponent) components.get(key);
        }
        MessageComponent component = new MessageComponent(this);
        components.put(key, component);
        return component;
    }
    /** 二维码操作组件 */
    public QrcodeComponent qrcode() {
        String key = QrcodeComponent.class.getName();
        if (components.containsKey(key)) {
            return (QrcodeComponent) components.get(key);
        }
        QrcodeComponent component = new QrcodeComponent(this);
        components.put(key, component);
        return component;
    }
    /** 场景操作组件 */
    public SceneComponent scene() {
        String key = SceneComponent.class.getName();
        if (components.containsKey(key)) {
            return (SceneComponent) components.get(key);
        }
        SceneComponent component = new SceneComponent(this);
        components.put(key, component);
        return component;
    }
    /** 营销位操作组件 */
    public TopicComponent topic() {
        String key = TopicComponent.class.getName();
        if (components.containsKey(key)) {
            return (TopicComponent) components.get(key);
        }
        TopicComponent component = new TopicComponent(this);
        components.put(key, component);
        return component;
    }
    /** 用户标签操作组件  */
    public UserLabelComponent userLabel() {
        String key = UserLabelComponent.class.getName();
        if (components.containsKey(key)) {
            return (UserLabelComponent) components.get(key);
        }
        UserLabelComponent component = new UserLabelComponent(this);
        components.put(key, component);
        return component;
    }

	public String getAppId() {
		return appId;
	}
	public void setAppId(String appId) {
		this.appId = appId;
	}
	public AlipayConfig getAlipayConfig() {
		return alipayConfig;
	}
	public void setAlipayConfig(AlipayConfig alipayConfig) {
		this.alipayConfig = alipayConfig;
	}
	public AlipayPayConfig getAlipayPayConfig() {
		return alipayPayConfig;
	}
	public void setAlipayPayConfig(AlipayPayConfig alipayPayConfig) {
		this.alipayPayConfig = alipayPayConfig;
	}
	public ITokenLoader getTokenLoader() {
		return tokenLoader;
	}
	public void setTokenLoader(ITokenLoader tokenLoader) {
		this.tokenLoader = tokenLoader;
	}
    
	
}
